package common.impl;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class VerifyCode{
    private static VerifyCode instance ;
    private final String ATTRIBUTE_NAME = "verifyCode";
    private final int CODE_LENGTH = 4;
    private final static String RAND_RANGE = "1234567890";   
    private String[] FontFamily={"Times New Roman","宋体","黑体","Arial Unicode MS","Lucida Sans","Times"};
	private boolean ROTATE_FLAG=true;
	private int Height = 35;
	private final static char[] CHARS = RAND_RANGE.toCharArray();
	public static VerifyCode getInstance(){
        if(instance == null)
        	instance = new VerifyCode();
        return instance;
    }
	/*
	 * 获取随机字符串
	 */
    public String getRandString(Integer len){
    	if(null == len || len==0)
    		len=CODE_LENGTH;
    	Random rand = new Random();
    	StringBuffer vcode = new StringBuffer();
        for (int i = 0; i < len; i++)
        	vcode.append(CHARS[rand.nextInt(CHARS.length)]);
        return vcode.toString();
    }
    /*
	 * 获取6字符串
	 */
	public static String getVerifyCode6(Integer len) {
		if (null == len || len == 0)
			len = 6;
		Random rand = new Random();
		StringBuffer vcode = new StringBuffer();
		for (int i = 0; i < len; i++)
			vcode.append(CHARS[rand.nextInt(CHARS.length)]);
		return vcode.toString();
	}
	
    /*
     * 获取随机颜色值
     */
    private Color getRandColor(int ll, int ul){
    	Random rand = new Random();
    	if (ll > 255) ll = 255;
        if (ll < 1) ll = 1;
        if (ul > 255) ul = 255;
        if (ul < 1) ul = 1;
        if (ul == ll) ul = ll + 1;
        int r = rand.nextInt(ul - ll) + ll;
        int g = rand.nextInt(ul - ll) + ll;
        int b = rand.nextInt(ul - ll) + ll;
        Color color = new Color(r,g,b);
        return color;
    }
   
    public String getVerifyCode(){
    	return this.ATTRIBUTE_NAME;
    }
    
    /*
     * 通过字符串生成验证码图形
     * @verifyCode 验证码
     */
    private BufferedImage getImage(String verifyCode){
    	int width = CODE_LENGTH * 18 + 20;
        BufferedImage image = new BufferedImage(width, Height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();
        Graphics2D g2 = (Graphics2D) graphics;
        g2.setColor(new Color(255,255,255));
        g2.fillRect(0, 0, width, Height);
        int fontsize;
		int fontstyle = 0;
		double oldrot = 0;
		g2.setColor(getRandColor(50,150));
		for (int i=0; i<CODE_LENGTH; i++){
			Random rand = new Random();
			fontsize = Math.abs(rand.nextInt(26));
		    // 18-24 fontsize
            if(fontsize < 13)
            	fontsize += 13;
            if(fontsize < 20)
            	fontsize += 6;
            fontstyle=rand.nextInt(6) ;
            g2.setFont(new Font(FontFamily[rand.nextInt(5)], fontstyle, fontsize));
            double rot = -0.25 + Math.abs(Math.toRadians(rand.nextInt(25)));
           
            if(ROTATE_FLAG){
            	g2.rotate(-oldrot,10,15);
            	oldrot = rot;
            	g2.rotate(rot,15 * i + 8 , 15);
            }
            g2.setStroke(new BasicStroke(2));
            String temp = verifyCode.substring(i, i+1);
            g2.drawString(temp, 18 * i + 10, 20);
        }
		g2.setStroke(new BasicStroke(1)); 
    	g2.setColor(new Color(0,0,0));
        for(int i=0;i<4;i++){
        	Random rand = new Random();
        	int x = rand.nextInt(width);
        	int y = rand.nextInt(30);
        	g2.drawLine(x,y,x+rand.nextInt(15),y-5+rand.nextInt(10));
        }
  		g2.dispose();
        return image;
    }
    /**
     * 发送验证码到客户端
     * @param request 
     * @param response 
     * */
    public synchronized void generateCode(HttpServletRequest request,HttpServletResponse response){
        response.setContentType("image/jpeg");
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 2000);
        String verifyCode = getRandString(CODE_LENGTH);
        BufferedImage bi = getImage(verifyCode);
        request.getSession().setAttribute("needVerifyCode", "1"); 
        request.getSession().setAttribute(ATTRIBUTE_NAME, verifyCode);
        try{
            ServletOutputStream outStream = response.getOutputStream();
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outStream);
            encoder.encode(bi);
            outStream.flush();
            outStream.close();
        }catch(IOException ex){
            ex.printStackTrace();
        }
    }
    
    /**
     * 
     * @param request
     */
    public synchronized void generateCode(HttpServletRequest request,String code){
        request.getSession().setAttribute("needVerifyCode", "1"); 
        request.getSession().setAttribute(ATTRIBUTE_NAME, code);
    }
        /**
     * 验证
     * @param request 
     * @return 正确 true 错误 false
     * */
    public synchronized boolean check(HttpServletRequest request,String vcode){
        if(null == vcode)
        	return false;
        vcode = vcode.toUpperCase();
        String vcode1 = (String)request.getSession().getAttribute(ATTRIBUTE_NAME);
    	if (vcode.equalsIgnoreCase(vcode1)){
            request.getSession().removeAttribute(ATTRIBUTE_NAME);
            return true;
        }else{
        	request.getSession().setAttribute(ATTRIBUTE_NAME, getRandString(CODE_LENGTH));
        }
        return false;
    }
}